﻿using Elastic.Apm.StackExchange.Redis;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using StackExchange.Redis;
using XYS.Core.Models;
using XYS.Service.Core.Service;

namespace XYS.Service.Core;

/// <summary>
/// 缓存服务 相关配置
/// </summary>
public static class CacheExtension
{
    /// <summary>
    /// 增加分布式缓存
    /// </summary>
    /// <param name="builder"></param>
    /// <param name="logger"></param>
    /// <returns></returns>
    public static WebApplicationBuilder AddCache(this WebApplicationBuilder builder, ILogger logger)
    {
        logger.Log(LogLevel.Information, "注册本地缓存");
        //注入 IMemoryCache
        builder.Services.AddSingleton<IMemoryCache, MemoryCache>();

        //获取配置项中的Redis配置
        var redisSetting = builder.Configuration.GetSection("RedisSetting").Get<RedisSetting>();
        var cnfKeys = builder.Configuration.AsEnumerable().Select(e => e.Key).ToList();
        if (redisSetting == null)
        {
            logger.LogError("缺少配置项：RedisSetting");
            throw new Exception("缺少配置项：RedisSetting");
        }

        //获取缓存用的databaseIndex
        var cacheSetting = builder.Configuration.GetSection("CacheSetting");

        var redisDataBaseIndex = cacheSetting.GetValue<int>("DatabaseIndex");
        string redisConnectString = $"{redisSetting.Host}:{redisSetting.Port},password={redisSetting.Password}";
        if (!string.IsNullOrWhiteSpace(redisSetting.UserName))
        {
            redisConnectString = $"{redisSetting.Host}:{redisSetting.Port},password={redisSetting.Password},user={redisSetting.UserName}";
        }

        //创建连接
        var configurationOptions = ConfigurationOptions.Parse(redisConnectString);
        configurationOptions.SyncTimeout = int.MaxValue;
        configurationOptions.ConnectTimeout = int.MaxValue;

        logger.Log(LogLevel.Information, $"启用Redis缓存，DatabaseIndex：{redisDataBaseIndex}");

        var connection = ConnectionMultiplexer.Connect(configurationOptions);
        connection.UseElasticApm();
        var db = connection.GetDatabase();

        //注入 Redis缓存服务
        builder.Services.AddSingleton<ICache>(s => new Cache(db));
        logger.Log(LogLevel.Information, $"启用Redis缓存");


        builder.Services.AddSingleton<LockService>();

        //通过缓存服务 获取当前登录人信息
        builder.Services.AddScoped(serviceProvider =>
        {
            //TODO 接入正确的接口，获取当前登录人信息
            return CurrentUserInfo.CreateAnonymousUser();
        });

        return builder;
    }

}
